/*
transformIterator:  Fancy iterator, this iterator brings a value from
                    a collection with a trasformation provided by a
                    transform function on each element in the collection.
    Copyright (C) 2012  Jorge E. A. Atala
                        FuDePAN
    This file is part of the Fui Proyect.

    Fui is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Fui is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Fui.  If not, see <http://www.gnu.org/licenses/>.
*/

/*
 * For more information, see http://code.google.com/p/thrust/
 *
 * \class TransformIterator
 * \addtogroup fancyiterator Fancy Iterators
 * \ingroup iterators
 */


#ifndef TRANSFORM_ITERATOR_H
#   define TRANSFORM_ITERATOR_H
#   include "iteratorBase.h"

namespace fui
{
template<class UnaryFunction, class Iterator>
class TransformIterator : public IteratorBase<typename Iterator::value_type>
{
private:

    Iterator it;
    UnaryFunction function;
    typedef typename UnaryFunction::argument_type Argument;
    typedef typename UnaryFunction::result_type Result;
public:

    /*! This constructor takes as arguments an \c Iterator and an \c UnaryFunction
     *  and copies them to a new \p transform_iterator.
     *
     *  \param it An \c Iterator pointing to the input to this \p transform_iterator's \c UnaryFunction.
     *  \param function An \c UnaryFunction used to transform the objects pointed to by \p it.
     */
    TransformIterator(const Iterator& it, UnaryFunction function);

    inline Result operator*() const;

    inline TransformIterator<UnaryFunction, Iterator> operator+(const size_t index) const;

    inline TransformIterator<UnaryFunction, Iterator> operator-(const size_t index) const;

    inline TransformIterator<UnaryFunction, Iterator> operator-(const TransformIterator<UnaryFunction, Iterator> other) const;

    inline TransformIterator<UnaryFunction, Iterator>& operator++();

    inline TransformIterator<UnaryFunction, Iterator>& operator--();

    inline TransformIterator<UnaryFunction, Iterator> operator++(const int);

    inline TransformIterator<UnaryFunction, Iterator> operator--(const int);

    inline bool operator==(const TransformIterator<UnaryFunction, Iterator>& other)const;

    inline bool operator!=(const TransformIterator<UnaryFunction, Iterator>& other)const;

    inline bool operator<(const TransformIterator<UnaryFunction, Iterator>& other)const;
};
}
#define TRANSFORM_ITERATOR_IMP
#   include "transformIterator_imp.h"
#undef TRANSFORM_ITERATOR_IMP

#endif
